home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Gfx / Edit / TSMorph / src / apack.asm next >
Assembly Source File  |  1994-10-30  |  8KB  |  254 lines

  1.  
  2. **************************************************************** 
  3. *  Copyright 1988 by CREATIVE FOCUS.  This code is freely 
  4. *  distributable as long as this notice is retained and no 
  5. *  other conditions are imposed upon its redistribution. 
  6. *  APACK.ASM --  
  7. *  A fully compatible replacement for Electronic Arts' PACKER.C 
  8. *  routine.  Converts data according to the IFF ILBM cmpByteRun1 
  9. *  compression protocol: 
  10. *     control bytes: 
  11. *        n =  0.. 127:   followed by n+1 bytes of data; 
  12. *        n = -1..-127:   followed by byte to be repeated -n+1 times; 
  13. *        n =     -128:   don't do no nada. 
  14. *     calling format: 
  15. *        long packrow(from, too, amt) 
  16. *           char **from, /* pointer to source data pointer */ 
  17. *                **too;  /* pointer to destination data pointer */ 
  18. *           long amt;    /* number of bytes to compress */ 
  19. *        return(number of bytes written to destination); 
  20. *     effects: 
  21. *         *from = *from + amt, and *too = *too + return; 
  22. *         return is "smart," that is, not greater than 
  23. *         MaxPackedSize = amt + ((amt+127) >> 7). 
  24. *     By commenting out CHECK (below) you disable checking for runs 
  25. *     exceeding 128 bytes.  That CHECK is not needed if you are sure 
  26. *     the amt to be compressed is always 128 or less. 
  27. *  !!! DISCLAIMER !!!  You use this code entirely at your own 
  28. *  risk.  I don't warrantee its fitness for any purpose.  I 
  29. *  can't even guarantee the accuracy of anything I've said 
  30. *  about it, though I've tried my damndest to get it right. 
  31. *  I may, in fact, be completely out of my tiny little mind :-). 
  32. *  That being said, I can be reached for questions, comments, 
  33. *  or concerns at: 
  34. *        Dr. Gerald Hull 
  35. *        CREATIVE FOCUS 
  36. *        12 White Street 
  37. *        Binghamton, N.Y.  13901 
  38. *        (607) 648-4082 
  39. *        bix:    ghull 
  40. *        PLink:  DRJERRY 
  41. *************************************************************** 
  42.  
  43. * edited by mjp to compile with SAS/C 5.10
  44.  
  45.    xdef  _packrow 
  46.  
  47.     section code
  48.  
  49. *a0    equr  a0                -> beginning of replicate run (if any) 
  50. *a1    equr  a1                -> end+1 of input line 
  51. *a2    equr  a2                -> beginning of literal run (if any) 
  52. *a3    equr  a3                -> end+1 of lit and/or rep run (if any) 
  53. *a4    equr  a4                -> end+1 of output line current pos 
  54. *a5    equr  a6                frame pointer 
  55. *a7    equr  a7                stack pointer 
  56.  
  57. *d0    equr  d0                return value 
  58. *d1    equr  d1                check for maximum run = MAX 
  59. *d2    equr  d2                amount 
  60. *d3    equr  d3                character 
  61.  
  62. *d2/d3/a2/a3/a4  reg   d2/d3/a2/a3/a4 
  63.  
  64. FRM   equ   8                 input line address 
  65. TOO   equ   12                output line address 
  66. AMT   equ   16                length of input line 
  67.  
  68. MAX   equ   128               maximum encodable output run 
  69. CHECK equ   1                 turns on maximum row checking 
  70.  
  71.  
  72. _packrow 
  73.  
  74.  
  75. ***************     CASE 0:   GRAB PARAMS & INITIALIZE 
  76. CAS0 
  77.       link     a5,#0 
  78.       movem.l  d2/d3/a2/a3/a4,-(a7) 
  79.       movea.l  FRM(a5),a2 
  80.       movea.l  (a2),a2        a2 = *from 
  81.       movea.l  a2,a3          a3 = a2 
  82.       movea.l  a3,a1 
  83.       adda.l   AMT(a5),a1     a1 = a2 + amt 
  84.       movea.l  TOO(a5),a4 
  85.       movea.l  (a4),a4        a4 = *too 
  86.  
  87.  
  88. ***************     CASE 1:   LITERAL RUN 
  89. CAS1 
  90.       movea.l  a3,a0          adjust a0 (no replicates yet!) 
  91.       move.b   (a3)+,d3       grab character 
  92.       cmpa.l   a3,a1          if input is finished 
  93.       beq.s    CAS5              branch to case 5 
  94.  
  95.       ifd      CHECK 
  96.       move.l   a3,d1 
  97.       sub.l    a2,d1 
  98.       cmpi     #MAX,d1        if run has reached MAX 
  99.       beq.s    CAS6              branch to case 6 
  100.       endc 
  101.  
  102.       cmp.b    (a3),d3        if next character != d3 
  103.       bne.s    CAS1              stay in case 1 
  104.  
  105. *                             else fall into case 2 
  106.  
  107.  
  108. ***************     CASE 2:   AT LEAST 2 BYTE REPEAT 
  109. CAS2 
  110.       move.b   (a3)+,d3       grab character 
  111.       cmpa.l   a3,a1          if input is finished 
  112.       beq.s    CAS7              branch to case 7 
  113.  
  114.       ifd      CHECK 
  115.       move.l   a3,d1 
  116.       sub.l    a2,d1 
  117.       cmpi     #MAX,d1        if run has reached MAX 
  118.       beq.s    CAS6              branch to case 6 
  119.       endc 
  120.  
  121.       cmp.b    (a3),d3        if next character != d3 
  122.       bne.s    CAS1              branch to case 1 
  123.  
  124. *                             else fall into case 3 
  125.  
  126.  
  127. ***************     CASE 3:   REPLICATE RUN 
  128. CAS3 
  129.       move.b   (a3)+,d3       grab character 
  130.       cmpa.l   a3,a1          if input is finished 
  131.       beq.s    CAS7              branch to case 7 
  132.  
  133.       ifd      CHECK 
  134.       move.l   a3,d1 
  135.       sub.l    a0,d1 
  136.       cmpi     #MAX,d1        if run has reached MAX 
  137.       beq.s    CAS4              branch to case 4 
  138.       endc 
  139.  
  140.       cmp.b    (a3),d3        if next character = d3 
  141.       beq.s    CAS3              stay in case 3 
  142.  
  143. *                             else fall into case 4 
  144.  
  145.  
  146. ***************     CASE 4:   LIT AND/OR REP DUMP & CONTINUE 
  147. CAS4 
  148.       move.l   a0,d2 
  149.       sub.l    a2,d2          d2 = a0 - a2 
  150. *                             if no literal run 
  151.       beq.s    C41               branch to replicate run 
  152.  
  153.       subq     #1,d2          d2 = d2 - 1 
  154.       move.b   d2,(a4)+       output literal control byte 
  155.  
  156. C40   move.b   (a2)+,(a4)+    output literal run 
  157.       dbra     d2,C40 
  158.  
  159. C41   move.l   a0,d2 
  160.       sub.l    a3,d2          d2 = a0 - a3 (negative result!) 
  161.       addq     #1,d2          d2 = d2 + 1 
  162.       move.b   d2,(a4)+       output replicate control byte 
  163.       move.b   d3,(a4)+       output repeated character 
  164.       movea.l  a3,a2          reset a2 
  165.       bra.s    CAS1           branch to case 1 (not done) 
  166.  
  167.  
  168. ***************     CASE 5:   LITERAL DUMP & QUIT 
  169. CAS5 
  170.       move.l   a3,d2 
  171.       sub.l    a2,d2          d2 = a3 - a2 (positive result > 0) 
  172.       subq     #1,d2          d2 = d2 - 1 
  173.       move.b   d2,(a4)+       output literal control byte 
  174.  
  175. C50   move.b   (a2)+,(a4)+    output literal run 
  176.       dbra     d2,C50 
  177.  
  178.       bra.s    CAS8           branch to case 8 (done) 
  179.  
  180.  
  181.       ifd      CHECK 
  182.  
  183. ***************     CASE 6:   LITERAL DUMP & CONTINUE 
  184. CAS6 
  185.       move.l   a3,d2 
  186.       sub.l    a2,d2          d2 = a3 - a2 (positive result > 0) 
  187.       subq     #1,d2          d2 = d2 - 1 
  188.       move.b   d2,(a4)+       output literal control byte 
  189.  
  190. C60   move.b   (a2)+,(a4)+    output literal run 
  191.       dbra     d2,C60 
  192.  
  193.       bra      CAS1           branch to case 1 (not done) 
  194.  
  195.       endc 
  196.  
  197.  
  198. ***************     CASE 7:   LIT AND/OR REP DUMP & FINISH 
  199. CAS7 
  200.       move.l   a0,d2 
  201.       sub.l    a2,d2          d2 = a0 - a2 (positive result > 0) 
  202. *                             if no literal run 
  203.       beq.s    C71               branch to replicate run 
  204.  
  205.       subq     #1,d2          d2 = d2 - 1 
  206.       move.b   d2,(a4)+       output literal control byte 
  207.  
  208. C70   move.b   (a2)+,(a4)+    output literal run 
  209.       dbra     d2,C70 
  210.  
  211. C71   move.l   a0,d2 
  212.       sub.l    a3,d2          d2 = a0 - a3 (negative result) 
  213.       addq     #1,d2          d2 = d2 + 1 
  214.       move.b   d2,(a4)+       output replicate control byte 
  215.       move.b   d3,(a4)+       output repeated character 
  216.  
  217. *                             fall into case 8 
  218.  
  219.  
  220. ***************     CASE 8:   ADJUST PARAMS & RETURN VALUE 
  221. CAS8 
  222.       movea.l  FRM(a5),a0     a0 = **from 
  223.       move.l   a3,(a0)        *from = *from + amt 
  224.       movea.l  TOO(a5),a0     a0 = **too 
  225.  
  226.       move.l   a4,d0 
  227.       sub.l    (a0),d0       return = a4 - *too  
  228.  
  229.       move.l   a4,(a0)       *too = *too + return 
  230.       movem.l  (a7)+,d2/d3/a2/a3/a4 
  231.       UNLK     a5 
  232.       rts 
  233.  
  234.       end
  235.  
  236.  
  237.